package io.renren.modules.yckj.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.renren.common.constant.Constant;
import io.renren.common.exception.ErrorCode;
import io.renren.common.exception.RenException;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.common.utils.ConvertUtils;
import io.renren.common.utils.TreeUtils;
import io.renren.modules.yckj.dao.CateDao;
import io.renren.modules.yckj.dto.CateDTO;
import io.renren.modules.yckj.entity.CateEntity;
import io.renren.modules.yckj.service.CateService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 项目分类表
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2025-04-22
 */
@Service
public class CateServiceImpl extends CrudServiceImpl<CateDao, CateEntity, CateDTO> implements CateService {

    @Override
    public QueryWrapper<CateEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");
        Object status = params.get("status");
        Object hot = params.get("hot");

        QueryWrapper<CateEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
        wrapper.eq(ObjectUtil.isAllNotEmpty(status), "status", status);
        wrapper.eq(ObjectUtil.isAllNotEmpty(hot), "hot", hot);
        wrapper.orderByAsc("sort");
        return wrapper;
    }


    @Override
    public List<CateDTO> getList(Map<String, Object> params) {

        //查询分类列表
        List<CateEntity> entityList = baseDao.getList(params);

        List<CateDTO> dtoList = ConvertUtils.sourceToTarget(entityList, CateDTO.class);

        return TreeUtils.build(dtoList);
    }

    @Override
    public CateDTO get(Long id) {
        //超级管理员，部门ID为null
        if (id == null) {
            return null;
        }
        CateEntity entity = baseDao.getById(id);
        return ConvertUtils.sourceToTarget(entity, CateDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(CateDTO dto) {
        CateEntity entity = ConvertUtils.sourceToTarget(dto, CateEntity.class);

        entity.setPids(getPidList(entity.getPid()));
        return insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(CateDTO dto) {
        CateEntity entity = ConvertUtils.sourceToTarget(dto, CateEntity.class);

        //上级不能为自身
        if (entity.getId().equals(entity.getPid())) {
            throw new RenException(ErrorCode.SUPERIOR_CATE_ERROR);
        }

        //上级不能为下级
        List<Long> subList = getSubIdList(entity.getId());
        if (subList.contains(entity.getPid())) {
            throw new RenException(ErrorCode.SUPERIOR_CATE_ERROR);
        }

        entity.setPids(getPidList(entity.getPid()));
        return updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        //判断是否有子级
        List<Long> subList = getSubIdList(id);
        if (subList.size() > 1) {
            throw new RenException(ErrorCode.DEPT_SUB_DELETE_ERROR);
        }

        //判断部门下面是否有用户
//        int count = sysUserDao.getCountByDeptId(id);
//        if (count > 0) {
//            throw new RenException(ErrorCode.DEPT_USER_DELETE_ERROR);
//        }

        //删除
        return baseDao.deleteById(id) > 0;
    }

    @Override
    public List<Long> getSubIdList(Long id) {
        List<Long> deptIdList = baseDao.getSubIdList("%" + id + "%");
        deptIdList.add(id);

        return deptIdList;
    }

    /**
     * 获取所有上级部门ID
     *
     * @param pid 上级ID
     */
    private String getPidList(Long pid) {
        //顶级，无上级
        if (Constant.DEPT_ROOT.equals(pid)) {
            return Constant.DEPT_ROOT + "";
        }

        //所有的id、pid列表
        List<CateEntity> cateList = baseDao.getIdAndPidList();

        //list转map
        Map<Long, CateEntity> map = new HashMap<>(cateList.size());
        for (CateEntity entity : cateList) {
            map.put(entity.getId(), entity);
        }

        //递归查询所有上级ID列表
        List<Long> pidList = new ArrayList<>();
        getPidTree(pid, map, pidList);

        return StringUtils.join(pidList, ",");
    }

    private void getPidTree(Long pid, Map<Long, CateEntity> map, List<Long> pidList) {
        //顶级，无上级
        if (Constant.DEPT_ROOT.equals(pid)) {
            return;
        }

        //上级存在
        CateEntity parent = map.get(pid);
        if (parent != null) {
            getPidTree(parent.getPid(), map, pidList);
        }

        pidList.add(pid);
    }
}